home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / c / snippet.exe / HUGEREAD.C < prev    next >
C/C++ Source or Header  |  1992-07-04  |  4KB  |  154 lines

  1. /*
  2. **  HUGEREAD.C - "Universal" PC read and write functions using huge data
  3. **               and far pointers.
  4. **
  5. **  public domain by Bob Stout
  6. **
  7. **  NOTES:
  8. **
  9. **  1. If these functions are called with a prototype in scope, passed
  10. **     parameters will be coerced to the proper data types.
  11. **
  12. **  2. Since these call read() and write(), all normal mode flags which
  13. **     are supported by individual compilers will be honored.
  14. **
  15. **  3. In small data memory models (S, T, and M), an intermediate buffer
  16. **     is allocated and used. In large data models (L and C), the data
  17. **     are read/written directly from/to target memory.
  18. */
  19.  
  20. #include <dos.h>
  21. #include <io.h>
  22. #include <stdlib.h>
  23. #include <stddef.h>
  24.  
  25. #ifndef min
  26.  #define min(x,y) (((x) <= (y)) ? (x) : (y))
  27. #endif
  28.  
  29. #ifndef MK_FP
  30.  #define MK_FP(seg,offset) \
  31.         ((void _far *)(((unsigned long)(seg)<<16) | (unsigned)(offset)))
  32. #endif
  33.  
  34. /*
  35. **  Get the largest buffer possible.
  36. */
  37.  
  38. static size_t gettmp(char **buf)
  39. {
  40.       static size_t bufsiz = 0;
  41.       static char *buffer = NULL;
  42.  
  43.       if (bufsiz)
  44.       {
  45.             *buf = buffer;
  46.             return bufsiz;
  47.       }
  48.       for (bufsiz = 0x4000; bufsiz >= 128; bufsiz >>= 1)
  49.       {
  50.             if (NULL != (buffer = (char *) malloc(bufsiz)))
  51.             {
  52.                   *buf = buffer;
  53.                   return bufsiz;
  54.             }
  55.       }
  56.       return 0;
  57. }
  58.  
  59. /*
  60. **  Normalize a far pointer
  61. */
  62.  
  63. void _far *farnormal(void _far *ptr)
  64. {
  65.       size_t seg, ofs;
  66.  
  67.       seg = FP_SEG(ptr);
  68.       ofs = FP_OFF(ptr);
  69.       return MK_FP(seg + (ofs >> 4), ofs & 0xf);
  70. }
  71.  
  72. /*
  73. **  Read any size block to anywhere in memory
  74. */
  75.  
  76. long hugeread(int fh, char _far *buf, long size)
  77. {
  78.       long count;
  79.       size_t bufsiz;
  80.       char *tmp;
  81.       long ercode = size;
  82.  
  83.       if (4 > sizeof(void *))
  84.       {
  85.             if (0 == (bufsiz = gettmp(&tmp)))
  86.                   return -1L;
  87.       }
  88.       else
  89.       {
  90.             tmp = (char *)buf;
  91.             bufsiz = 0x4000;
  92.       }
  93.  
  94.       while (0 < (count = min(size, (long)bufsiz)))
  95.       {
  96.             int i, numread = read(fh, tmp, (size_t)count);
  97.  
  98.             if (1 > numread || numread != (int)count)
  99.                   return -1L;
  100.             if (4 > sizeof(void *))
  101.             {
  102.                   for (i = count; i; --i)
  103.                         buf[i] = tmp[i];
  104.             }
  105.             buf = farnormal(buf + count);
  106.             size -= count;
  107.             if (2 < sizeof(void *))
  108.                   tmp = (char *)buf;
  109.       }
  110.       return ercode;
  111. }
  112.  
  113. /*
  114. **  Write any size block from anywhere in memory
  115. */
  116.  
  117. long hugewrite(int fh, char _far *buf, long size)
  118. {
  119.       long count;
  120.       size_t bufsiz;
  121.       char *tmp;
  122.       long ercode = size;
  123.  
  124.       if (4 > sizeof(void *))
  125.       {
  126.             if (0 == (bufsiz = gettmp(&tmp)))
  127.                   return -1L;
  128.       }
  129.       else
  130.       {
  131.             tmp = (char *)buf;
  132.             bufsiz = 0x4000;
  133.       }
  134.  
  135.       while (0 < (count = min(size, (long)bufsiz)))
  136.       {
  137.             int i, numwrite;
  138.  
  139.             if (4 > sizeof(void *))
  140.             {
  141.                   for (i = count; i; --i)
  142.                         tmp[i] = buf[i];
  143.             }
  144.             numwrite = write(fh, tmp, (size_t)count);
  145.             if (1 > numwrite || numwrite != (int)count)
  146.                   return -1L;
  147.             buf = farnormal(buf + count);
  148.             size -= count;
  149.             if (2 < sizeof(void *))
  150.                   tmp = (char *)buf;
  151.       }
  152.       return ercode;
  153. }
  154.